package cluedo.gui;


import java.awt.*;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import java.util.LinkedList;


import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

import cluedo.Card;
import cluedo.Character;
import cluedo.Player;
import cluedo.Room;
import cluedo.Weapon;
import cluedo.Zombie;

import static cluedo.Player.log;

/** Il tavolo di gioco; I metodi qui implementati gestiscono gli eventi generati dall'interfaccia grafica*/

public class MainWindow implements ActionListener, WindowListener{

	/**
	 * La MainWindow
	 */
	private JFrame frame;
	
	/**
	 * il giocatore associato alla finestra MainWindow
	 */
	private Player myPlayer;
	
	/**
	 * pannelli che compongono la MainWindow
	 */
	private CenterPanel centerPanel;
	private EastPanel eastPanel;
	private WestPanel westPanel;
	
	
	/**
	 * finestra di formulazione ipotesi/soluzione
	 */
	private JDialog formulateWind;
	
	/**
	 * finestra vincitore/perdente
	 */
	private JDialog endWind;
	
	/**
	 * Finestra che mostra le istruzioni di gioco
	 */
	private Help helpWind;
	
	/**
	 * Finestra visualizzata quando la pedina di un player entra in una stanza
	 */
	private JDialog roomWind;
	
	/**
	 * Finestra che mostra il risultato di un'ipotesi
	 */
	private JDialog resAssumptionWind;

	/**
	 * Variabile per dimensionare carte nella finestra vincitore/perdente
	 */
	private final int SCALECARD=180;
	
	/**
	 * Spazio tra le carte nella finestra vincitore/perdente
	 */
	private final int SPACEBETWCARDS=10;
	
	/**
	 * Carte soluzioni del delitto
	 */
	private Character character=null;
	private Weapon weapon=null;
	private Room room=null;	
	
	// Gestione drag&drop
	/**
	 * controllo se la carta trascinata e' un'arma
	 */
	public boolean isWeapDragged=false;
	/**
	 * controllo se la carta trascinata e' un personaggio
	 */
	public boolean isChDragged=false;
	
	
	/***
	 * carte draggate dal tabellone
	 */
	public Weapon draggedWeap = null;
	public Character draggedCh = null;
	public Room draggedRoom=null;
	
	/***
	 * carte droppate nella finestra soluzione/ipotesi
	 */
	private Weapon droppedWeap = null;
	private Character droppedCh = null;
	private Room droppedRoom = null;
	
	/**
	 * spazi nella finestra di formulazione ipotesi/soluzione in cui droppare carte
	 */
	private JPanel spaceWeapon,spaceCharacter,spaceRoom;
	
	/**
	 * controlla quante carte sono state droppate correttamente 
	 */
	private int numDroppedCard=0;
	
	
	/**
	 * finestra per confutare l'ipotesi
	 */
	private JDialog refuteWind;
	
	/**
	 * Contiene il messaggio informativo che segnala al player che sta formulando un'ipotesi/soluzione 
	 * con carte che sono gia' state scartate
	 */
	private JTextPane warningMessage;
	
	/**
	 * La finestra che gestisce il click dell'utente sul tasto esci o sulla X di chiusura MainWindow
	 */
	private JDialog exitWind;
	
	/**
	 * il player a cui devo confutare l'ipotesi
	 */
	private Zombie refutePlayer=null;
	
	/**
	 * la carta per confutare un'ipotesi
	 */
	private Card refuteCard=null;
	
	/**
	 * l'etichetta che contiene l'immagine della carta che confuta l'ipotesi
	 */
	private JLabel refuteLab = null;
	
	/**
	 * Bottone invia ipotesi/tesi
	 */
	
	private JButton sendBtn;
	
	/**
	 *  numero ottenuto dal lancio del dado
	 */
	private int diceNum=-1;
	
	/**
	 * controlla se il dado e' gia' stato tirato
	 */
	private boolean isDiceThrow=false;
	
	/**
	 * per verificare se l'ipotesi che ho formulato e' stata controllata
	 */
	private boolean isAssumptionChecked=false;
	
	/**
	 * e' true se sto formulando una soluzione
	 */
	private boolean solutionTime=false;
	
	/**
	 * Variabile usata per controllare se e' il mio turno
	 */
	private boolean myTurn=false;
	
	/**
	 * Avvia la creazione della finestra (MainWindow)
	 * @param player il giocatore associato alla finestra
	 */
	public MainWindow(Player myPlayer) {
		this.myPlayer=myPlayer;
		log.printLog("MainWindow: inizio la creazione della MainWindow");
		initialize();
	}
	
	/**
	 * Inizializza il contenuto della MainWindow
	 */
	private void initialize() {
		frame = new JFrame("The Amazing Cluedo! - "+ myPlayer +" ("+ myPlayer.getPawn().getName() +") risolvi il mistero.");
		
		//System.out.println("E' il thread della grafica: "+EventQueue.isDispatchThread());
		
		frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		frame.addWindowListener(this);
		
		JPanel contentPane = new JPanel();
		contentPane.setBackground(Color.BLACK);
		
		contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.X_AXIS));
		
		westPanel=new WestPanel(myPlayer,this);
		contentPane.add(westPanel,BorderLayout.LINE_START);
		
		JPanel innerPane= new JPanel();
		innerPane.setLayout(new BorderLayout(0, 0));
		
		centerPanel = new CenterPanel(myPlayer,this);
		innerPane.add(centerPanel, BorderLayout.CENTER);
		
		JPanel northPanel = new JPanel();
		northPanel.setBackground(Color.BLACK);
		innerPane.add(northPanel,BorderLayout.PAGE_START);
		
		JPanel southPanel=new JPanel();
		southPanel.setBackground(Color.BLACK);
		innerPane.add(southPanel,BorderLayout.PAGE_END);

		
		eastPanel=new EastPanel(myPlayer,this);
		innerPane.add(eastPanel,BorderLayout.LINE_END);
		
		contentPane.add(innerPane);
		
		
		frame.setContentPane(contentPane);
		
		frame.pack();
		
		frame.setLocationRelativeTo(null);
		
		log.printLog("MainWindow: e' stata creata la MainWindow ma non e' ancora visibile");
		System.out.println("MainWindow: e' stata creata la MainWindow");
				
		//Se e' il mio turno avvio la finestra di gioco altrimenti finestra di attesa
		if(myPlayer.isMyTurn()){
			centerPanel.setPlayerTurn(true);
			eastPanel.enableGameBtn(isDiceThrow,isAssumptionChecked);
			log.printLog("MainWindow: il primo turno e' il mio; Invio l'info in multicastSendInfo per comunicare che il primo turno e' il mio");
			System.out.println("MainWindow: il primo turno e' il mio");
			myPlayer.multicastSendInfo(myPlayer.getNickname(),"","MyFirstTurn");
			
		}
		else{
			log.print("MainWindow: il primo turno non e' il mio");
			centerPanel.setPlayerTurn(false);
			eastPanel.disableAllGameBtn();
		}
	}
	
	/**
	 * Imposta la variabile di ipotesi controllata
	 * @param b true se ho effettuato un'ipotesi ed ho ricevuto la risposta alla mia ipotesi, false altrimenti
	 */
	public void setIsAssumptionChecked(boolean b){
		
		isAssumptionChecked=b;
	}
	
	/**
	 * Rende visibile la MainWindow
	 */
	public void showMainWindow() {
		frame.setVisible(true);
		log.printLog("MainWindow: la MainWindow e' diventata visibile");
	}
	
	/**
	 * Ottieni il riferimento all'area dei nickname posizionata nell'EastPanel
	 * @return l'area dei nickname
	 */
	public NicknamesArea getNicknameArea(){
		
		return eastPanel.getNicknamesArea();
		
	}
	
	/** Memorizza le carte della soluzione 
	 * 
	 * @param room la carta stanza della soluzione
	 * @param weapon la carta arma della soluzione
	 * @param character la carta personaggio della soluzione
	 * 
	 */
	public void setSol(Room room,Weapon weapon, Character character){
		
		this.weapon=weapon;
		this.room=room;
		this.character=character;
		log.printLog("MainWindow: ho memorizzato le carte della soluzione nei campi weapon,room e character della MainWindow");
		
	}
	
	/**
	 * Visualizza nell'eastPanel le carte che ho in mano
	 * @param cards le carte che mi sono state distribuite
	 */
	public void showMyCard(LinkedList<Card> cards){
		
		eastPanel.showMyCard(cards);
		
	}

	
	
	/**
	 * Crea la finestra vincitore/perdente
	 * @param opt puo' assumere i valori:
	 *  "alone" --> crea finestra vincitore perche' il player e' rimasto da solo
	 *  "loser" ---> crea finestra perdente perche' un player ha dato la soluzione corretta
	 *  "wrong" ---> crea finestra perdente perche' ho dato una soluzione errata
	 *  "winner" --> crea finestra vincitore per aver dato una soluzione corretta
	 *  @param winner il nome del vincitore o null se non c'e' ancora un vincitore
	 *  @param endGame  utilizzato se opt="wrong" , true se erano rimasti in 2 zombie-vivi e 
	 *  quindi questo errore causera' il termine della partita, altrimenti false
	 *  
	 */
	public void createWinLoseWind(Zombie winner, String opt, boolean endGame){
		
		if((!opt.equals("winner")) && (!opt.equals("loser")) && (!opt.equals("wrong")) && (!opt.equals("alone")))
			System.err.println("MainWindow: l'opzione passata al metodo createWinLoseWind non e' corretta");
		
		/* ho vinto senza che la MainWindow sia visibile, questo accade quando tutti gli altri player fanno crash quando gia'
		 * la finestra e' stata creata ma non e' ancora stato premuto su continua
		 */
		if((!frame.isVisible()) && (winner.getNickname().equals(myPlayer.getNickname()))){
			if(frame!=null) frame.dispose();
			myPlayer.abortNewPlay();
			return;
			
		}
		
		
		if(roomWind!=null){
			roomWind.dispose();
			roomWind=null;
		}
		
		if(helpWind!=null){
			helpWind.dispose();
			helpWind=null;
		}
		
		if(exitWind!=null){
			exitWind.dispose();
			exitWind=null;
		}
		
		if(resAssumptionWind!=null){
			resAssumptionWind.dispose();
			resAssumptionWind=null;
		}
			
		if(refuteWind!=null){
			refuteWind.dispose();
			refuteWind=null;
		}
		
		if(formulateWind!=null){
			formulateWind.dispose();
			formulateWind=null;
		}
		
		if(endWind!=null){
			endWind.dispose();
			endWind=null;
		}
		
		log.printLog("MainWindow: creo la finestra vincitore/perdente (endWind) con i seguenti parametri: ");
		
		if(winner!=null) log.printLog("winner --> "+winner.getNickname()+", ");
		else log.printLog("winner --> null, ");
		log.printLog("opt --> "+opt+", endGame --> "+endGame);
		
		/* rimuovo celle evidenziate se ve ne sono
		 * Gestisce la situazione in cui io sia rimasto l'ultimo giocatore (quindi ho vinto) in seguito 
		 * all'uscita  oppure al crash degli altri.
		 *  Ad esempio se avevo appena tirato il dado avro' le celle evidenziate 
		 * 	e quindi devo disattivarle
		 */
		getBoard().disableHighlightCells();
		
		//disabilito tasti di gioco
		eastPanel.stopTimer();
		eastPanel.disableAllGameBtn();
		
		endWind = new JDialog(frame);		
		endWind.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		endWind.addWindowListener(this);
		endWind.setBackground(Color.DARK_GRAY);
		
		
		JPanel endPane = new JPanel();
		
		endPane.setBackground(endWind.getBackground());

		
		endPane.setLayout(new BoxLayout(endPane, BoxLayout.Y_AXIS));
		
		JPanel endRes = new JPanel();
		endRes.setBackground(endWind.getBackground());

		endRes.setLayout(new BoxLayout(endRes, BoxLayout.X_AXIS));
		
		JTextPane endText= new JTextPane();
		endText.setBackground(endWind.getBackground());
		endText.setEditable(false);
		
        StyledDocument doc = endText.getStyledDocument();

		
		SimpleAttributeSet textStyle = new SimpleAttributeSet();
        StyleConstants.setForeground(textStyle,Color.WHITE);
        StyleConstants.setFontSize(textStyle, 16);
        StyleConstants.setBold(textStyle,true);

        
        SimpleAttributeSet textYellowStyle = new SimpleAttributeSet();
        StyleConstants.setForeground(textYellowStyle,Color.YELLOW);
        StyleConstants.setFontSize(textYellowStyle, 18);
        StyleConstants.setBold(textYellowStyle,true);
        
        boolean alone=false;
 		if(opt.equals("alone"))
 			alone=true;
 		
 		boolean wrong=false;
 		if(opt.equals("wrong"))
 			wrong=true;
		
		if(opt.equals("winner") || alone){
			
			try {
				if(!alone)
					doc.insertString(doc.getLength(), "\n Complimenti!!! \n Hai vinto la partita. " , textStyle);
				else
					doc.insertString(doc.getLength(), "\n Sei l'unico rimasto in gioco\n Hai vinto. " , textStyle);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
			endWind.setTitle("HAI VINTO");
			
			JLabel fireworks1=new JLabel();
			ImageIcon icon = new ImageIcon(MainWindow.class.getResource("/img/fireworks1.gif"));
			Image tmpImg= icon.getImage();
			tmpImg= tmpImg.getScaledInstance(-1, 80, Image.SCALE_DEFAULT);
			icon.setImage(tmpImg);
			fireworks1.setIcon(icon);
			
			JLabel fireworks2=new JLabel();
			icon = new ImageIcon(MainWindow.class.getResource("/img/fireworks2.gif"));
			tmpImg= icon.getImage();
			tmpImg= tmpImg.getScaledInstance(-1, 80, Image.SCALE_DEFAULT);
			icon.setImage(tmpImg);
			fireworks2.setIcon(icon);
			
			endRes.add(Box.createRigidArea(new Dimension(15,0)));
			endRes.add(fireworks1);
			endRes.add(endText);
			endRes.add(fireworks2);
			endRes.add(Box.createRigidArea(new Dimension(15,0)));

			
		}
		
	
		else if(opt.equals("loser") || wrong){
			
			SimpleAttributeSet nameStyle = new SimpleAttributeSet();

			if(winner!=null){
			StyleConstants.setForeground(nameStyle,myPlayer.getPlayerColor(winner.getNickname()));
			StyleConstants.setFontSize(nameStyle, 16);
			StyleConstants.setBold(nameStyle,true);
			}
			
			if(!wrong){		
	       
				try {
					doc.insertString(doc.getLength(), "\n La partita e' finita. \n " , textStyle);
					doc.insertString(doc.getLength(), winner.getNickname() , nameStyle);
					doc.insertString(doc.getLength(), " ha risolto il caso. " , textStyle);

				} catch (BadLocationException e) {
						e.printStackTrace();
				}
			
			endWind.setTitle("HAI PERSO");
			endRes.add(endText);
			}
			else{
			
				if(endGame){
					try {
						doc.insertString(doc.getLength(), "\n La soluzione data non e' corretta " , textStyle);
						doc.insertString(doc.getLength(), "\n\n Hai dato la vittoria a " , textStyle);
						doc.insertString(doc.getLength(), winner.getNickname()+" ", nameStyle);
					} catch (BadLocationException e) {
						e.printStackTrace();
					}
				}
				else{
					try {
						doc.insertString(doc.getLength(), "\n La soluzione data non e' corretta " , textStyle);
						doc.insertString(doc.getLength(), "\n\n Hai perso " , textYellowStyle);
					} catch (BadLocationException e) {
						e.printStackTrace();
					}
				}
			
				endWind.setTitle("HAI PERSO");
				endRes.add(endText);

			}
			
		}
		
		SimpleAttributeSet center = new SimpleAttributeSet();
        StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
        doc.setParagraphAttributes(0, doc.getLength(), center, false);

		
		JPanel endSolPane = new JPanel();
		
		endSolPane.setBackground(endWind.getBackground());
		
		endSolPane.setLayout(new BoxLayout(endSolPane, BoxLayout.X_AXIS));		
		
		JLabel solCharacter = new JLabel();
		JLabel solWeapon = new JLabel();
		JLabel solRoom = new JLabel();
				
		solCharacter.setIcon(this.character.getScaledImage(140));
		solCharacter.setToolTipText(this.character.getName());
		solWeapon.setIcon(this.weapon.getScaledImage(140));
		solWeapon.setToolTipText(this.weapon.getName());
		solRoom.setIcon(this.room.getScaledImage(140));
		solRoom.setToolTipText(this.room.getName());
		
		endSolPane.add(Box.createRigidArea(new Dimension(SPACEBETWCARDS,0)));
		endSolPane.add(solCharacter);
		endSolPane.add(Box.createRigidArea(new Dimension(SPACEBETWCARDS,0)));
		endSolPane.add(solWeapon);
		endSolPane.add(Box.createRigidArea(new Dimension(SPACEBETWCARDS,0)));
		endSolPane.add(solRoom);
		endSolPane.add(Box.createRigidArea(new Dimension(SPACEBETWCARDS,0)));
		
		JPanel endBtnPane = new JPanel();
		
		endBtnPane.setBackground(endWind.getBackground());
		
		endBtnPane.setLayout(new BoxLayout(endBtnPane, BoxLayout.X_AXIS));
		
		JButton endExit =new JButton("Esci da Cluedo");
		endExit.addActionListener(this);
		endExit.setActionCommand("endExit");
		
		JButton endGrp = new JButton("Cambia gruppo");
		endGrp.addActionListener(this);
		endGrp.setActionCommand("endGrp");
		
		if((!opt.equals("wrong")) || (opt.equals("wrong") && endGame)){ /* se il mio errore causa termine della partita posso rimanere nel gruppo 
		quindi mi serve il tasto ricomincia*/
			JButton endAgain = new JButton ("Ricomincia");
			endAgain.addActionListener(this);
			endAgain.setActionCommand("endAgain");
			endBtnPane.add(Box.createRigidArea(new Dimension(10,0)));
			endBtnPane.add(endAgain);
			endBtnPane.add(Box.createRigidArea(new Dimension(10,0)));

		}
		endBtnPane.add(endGrp);
		endBtnPane.add(Box.createRigidArea(new Dimension(10,0)));
		endBtnPane.add(endExit);
		endBtnPane.add(Box.createRigidArea(new Dimension(10,0)));

		endPane.add(Box.createRigidArea(new Dimension(0,3)));
		endPane.add(endRes);
		endPane.add(Box.createRigidArea(new Dimension(0,10)));
		endPane.add(endSolPane);
		endPane.add(Box.createRigidArea(new Dimension(0,10)));
		endPane.add(endBtnPane);
		endPane.add(Box.createRigidArea(new Dimension(0,10)));

		
		endWind.setContentPane(endPane);
				
		endWind.setModal(false); //voglio interagire con la chat
				
		endWind.pack();
		
		endWind.setLocationRelativeTo(centerPanel);
		
		endWind.setVisible(true);

		log.printLog("MainWindow: La finestra vincitore/perdente (endWind) e' stata creata");
	}
	
	/**
	 * Gestisce graficamente il passaggio del turno tra giocatori
	 * e richiama la finestra di lancio dadi se e' il mio turno
	 * @param player e' il giocatore che ha il prox turno
	 */
	public void plChangeTurn(Zombie player){
		/*
		 * In presenza di zombie-morti questo metodo puo' venire invocato piu' 
		 * volte ed in entrambe le volte essere myPlayer.isMyTurn()==true. 
		 * Il tutto viene gestito con la variabile myTurn
		 */
		NicknamesArea nickArea=getNicknameArea();
		nickArea.updatePlayerTurn(player);
				
		if(myPlayer.isMyTurn()==true && !myTurn){ //e' il mio turno
			if(resAssumptionWind!=null){
				resAssumptionWind.dispose();
				resAssumptionWind=null;
			}
			myTurn=true;
			log.printLog("MainWindow: E' il mio turno, invio il multicastSendInfo per comunicare che e' il mio turno");
			myPlayer.multicastSendInfo(myPlayer.getNickname(),"","MyTurn");
			isDiceThrow=false;
			centerPanel.setPlayerTurn(true);
			centerPanel.getBoard().showSecretPassage();
			eastPanel.enableGameBtn(isDiceThrow,isAssumptionChecked);
			
		} else if (myPlayer.isMyTurn()==false) {
			log.printLog("MainWindow: Non e' il mio turno, e' il turno di "+ player.getNickname());
			myTurn=false;
			centerPanel.setPlayerTurn(false);
			eastPanel.disableAllGameBtn();
		}
	}
	
	
	/**
	 * Gestisce l'entrata della pedina del player in una stanza
	 * @param x la coordinata x della pedina all'interno della stanza
	 * @param y la coordinata y della pedina all'interno della stanza
	 */
	public void enterInRoom(int x, int y){
		
		eastPanel.stopTimer();
		
		eastPanel.onlyTimerEndTurn();
		
		//avvia la creazione della finestra che chiede al player se vuole formulare un'ipotesi o dare la soluzione
		createRoomWind(x,y);
	}
	
	
	/**
	 * Crea la finestra che chiede al player se vuole formulare un'ipotesi o dare la soluzione 
	 * quando la sua pedina entra in una stanza
	 * @param x la coordinata x della pedina all'interno della stanza
	 * @param y la coordinata y della pedina all'interno della stanza
	 */
	public void createRoomWind(int x,int y){
	
	
		if(roomWind!=null){
			roomWind.dispose();
			roomWind=null;
		}
		
		roomWind= new JDialog(frame);
		roomWind.addWindowListener(this);
		roomWind.setModal(false); //voglio interagire con la chat
		roomWind.setBackground(Color.DARK_GRAY);
		
        String roomName = myPlayer.getPawn().getRoomName();

		log.printLog("MainWindow: Sono nella stanza "+roomName+"; sto creando la finestra roomWind");
        
        roomWind.setTitle(roomName);
	
		JPanel askFormulation= new JPanel();
		
		askFormulation.setBackground(roomWind.getBackground());
		
		askFormulation.setLayout(new BoxLayout(askFormulation, BoxLayout.Y_AXIS));
        
        JTextPane askText= new JTextPane();
        StyledDocument doc = askText.getStyledDocument();
        
        askText.setEditable(false);
        askText.setBackground(roomWind.getBackground());
             
        
        SimpleAttributeSet textWhite = new SimpleAttributeSet();
        StyleConstants.setForeground(textWhite,Color.WHITE);
        StyleConstants.setFontSize(textWhite, 12);
        StyleConstants.setBold(textWhite,true);
                
        ImageIcon img= new ImageIcon(MainWindow.class.getResource(Room.rooms.get(roomName)));
		Image tmpImg= img.getImage();
		tmpImg= tmpImg.getScaledInstance(-1, 80, Image.SCALE_SMOOTH);
		img.setImage(tmpImg);
		JLabel roomLbl=new JLabel();
		roomLbl.setIcon(img);
		
        StyleContext context = new StyleContext();
        Style labelStyle = context.getStyle(StyleContext.DEFAULT_STYLE);
        StyleConstants.setComponent(labelStyle, roomLbl);
		String labelText="Ignored";

                	     
        	try {
				doc.insertString(doc.getLength(),"\n Sei nella stanza "+roomName+" \n\n",textWhite);
				doc.insertString(doc.getLength(), labelText, labelStyle);
				doc.insertString(doc.getLength(),"\n\n Formula un'ipotesi o dai la soluzione ",textWhite);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
 
		
        SimpleAttributeSet center = new SimpleAttributeSet();
        StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
        doc.setParagraphAttributes(0, doc.getLength(), center, false);
		
        JPanel btn= new JPanel();
        btn.setBackground(roomWind.getBackground());
		btn.setLayout(new BoxLayout(btn, BoxLayout.X_AXIS));
		
		
		btn.add(Box.createRigidArea(new Dimension(10,0)));

		JButton solBtn= new JButton("Soluzione");
		solBtn.addActionListener(this);
		solBtn.setActionCommand("Soluzione");
		btn.add(solBtn);
		btn.add(Box.createRigidArea(new Dimension(10,0)));
					
		JButton assumpBtn= new JButton("Ipotesi");
		assumpBtn.addActionListener(this);
		assumpBtn.setActionCommand("Ipotesi");
		assumpBtn.setAlignmentX(Component.CENTER_ALIGNMENT);		
        btn.add(assumpBtn);
		btn.add(Box.createRigidArea(new Dimension(10,0)));

        
        askFormulation.add(askText);
        askFormulation.add(Box.createRigidArea(new Dimension(0,10)));
        askFormulation.add(btn); 
        askFormulation.add(Box.createRigidArea(new Dimension(0,10)));
        
        roomWind.add(askFormulation);
		roomWind.pack();
		
		if(x==-1 && y==-1){
			
			roomWind.setLocationRelativeTo(centerPanel);
			
		}
		else{
			int cy= y-roomWind.getHeight()/2;
			int maxY= frame.getHeight()-roomWind.getHeight();
			if (cy>maxY) cy=maxY; 
			roomWind.setLocation(x-roomWind.getWidth()/2,cy); //apro la finestra nella posizione in cui e' la mia pedina nella stanza
		}
		
		roomWind.setVisible(true);
		
		log.printLog("MainWindow: La finestra roomWind e' stata creata");
		
		
	}
	
	/**
	 * Gestisce graficamente il cambio di proprietario nella nicknames area
	 * @param player il nuovo proprietario 
	 */
	public void grpChangeOwner(Zombie player){
		NicknamesArea nickArea=getNicknameArea();
		nickArea.updateGroupOwner(player);
		
	}
	
	
	/** Aggiorna la chat con il messaggio ricevuto 
	 * 
	 * @param playerName il nickname del player che ha inviato il messaggio
	 * @param msg il messaggio di chat
	 * */
	public void updateChat(String playerName, String msg){
		
		this.eastPanel.updateChat(playerName,msg);
	}
	

	
	/** Gestisce la finestra di formulazione soluzione/ipotesi
	 * @param type "solution" se si deve formulare una soluzione
	 * 			   "assumption" se si deve formulare un'ipotesi
	 */
	
	public void showformulateWindow(String type){
		

		log.printLog("MainWindow: creo la finestra di formulazione ipotesi/soluzione (formulateWind) con il parametro type= "+type);
		
		numDroppedCard=0;

		formulateWind= new JDialog(frame);
		formulateWind.addWindowListener(this);
		formulateWind.setModal(false); //voglio interagire con la chat
		formulateWind.setResizable(false);
	
		
		formulateWind.setBackground(Color.DARK_GRAY);
                
        JPanel formulateWindContent = new JPanel();
		
        formulateWindContent.setBackground(formulateWind.getBackground());
        
        formulateWindContent.setLayout(new BoxLayout(formulateWindContent, BoxLayout.Y_AXIS));
        
        JTextPane solAssumpText= new JTextPane();
        StyledDocument doc = solAssumpText.getStyledDocument();
        
        solAssumpText.setEditable(false);
        solAssumpText.setBackground(formulateWind.getBackground());
        
        SimpleAttributeSet textYellow = new SimpleAttributeSet();
        StyleConstants.setForeground(textYellow,Color.YELLOW);
        StyleConstants.setFontSize(textYellow, 16);
        StyleConstants.setBold(textYellow,true);
        
        
        SimpleAttributeSet textWhite = new SimpleAttributeSet();
        StyleConstants.setForeground(textWhite,Color.WHITE);
        StyleConstants.setFontSize(textWhite, 14);
        StyleConstants.setBold(textWhite,true);

        
        if(type.equals("solution")){
        	     
        	formulateWind.setTitle("Formula la soluzione");
        	try {
				doc.insertString(doc.getLength(),"\nPuoi formulare la tua soluzione\n\nSe sbagli avrai perso e non potrai" +
						" piu' giocare\n\n",textWhite);
				doc.insertString(doc.getLength(),"  Se non sei sicuro premi Annulla  \n  e formula un'ipotesi  \n\n",textYellow);
				doc.insertString(doc.getLength(),"Altrimenti trascina il personaggio e l'arma\ndal tavolo di gioco alla finestra\n",textWhite);
				
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
        	
        }
        
        else if(type.equals("assumption")){
        	
        	formulateWind.setTitle("Formula l'ipotesi");
        	
        	try {
				doc.insertString(doc.getLength(),"\nStai effettuando un'ipotesi\n\nTrascina il personaggio e l'arma del " +
						"delitto\ndal tavolo di gioco alla finestra\n",textWhite);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
        	    			 		       
		        
        }
        
        
        else{
        	
        	System.err.println("MainWindow: errore il parametro "+ type +" non e' valido. Finestra di formulazione non creata");
        	return;
        	
        }
        
        
        SimpleAttributeSet center = new SimpleAttributeSet();
        StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
        doc.setParagraphAttributes(0, doc.getLength(), center, false);
        
        
                
        JPanel cardsPanel = new JPanel();
        
        cardsPanel.setBackground(formulateWind.getBackground());
        
		cardsPanel.setLayout(new BoxLayout(cardsPanel, BoxLayout.X_AXIS));

        
		Border loweredbevel = BorderFactory.createLoweredBevelBorder();
		
		int spWidth=-1;
				
		int spHeight=-1;
		
		spaceRoom = new JPanel();
		spaceRoom.setBackground(Color.DARK_GRAY);
        JLabel spRoom =new JLabel();
        spRoom.setForeground(Color.LIGHT_GRAY);
                
        if(type.equals("solution")){ //soluzione --> devo droppare anche la carta stanza
        	
        	spRoom.setText("Stanza");
            spRoom.setFont(new Font("SensSerif", Font.BOLD, 12));
            new MyDropTargetListener(spaceRoom,spRoom,3);
            Room room= new Room("Lounge"); //usato solo per ottenere la dimensione degli spazi in cui droppare le carte
            								//al posto di Lounge ci puo' andare il nome qualsiasi altra stanza
            spWidth=room.getScaledImage(140).getIconWidth();
    		spHeight=room.getScaledImage(140).getIconHeight();
   
        }
        
        else if(type.equals("assumption")){ //ipotesi --> carta stanza e' quella su cui mi trovo
        	        	
        	if(myPlayer.getPawn().getRoomName()!=null){
        		droppedRoom= new Room(myPlayer.getPawn().getRoomName());
            	spWidth=droppedRoom.getScaledImage(140).getIconWidth();
        		spHeight=droppedRoom.getScaledImage(140).getIconHeight();
            	
            	if(westPanel.isDiscardedCard(droppedRoom)){ //mostra se la carta e' stata scartata dalla soluzione
            		
            		Image tmpImg= droppedRoom.delCard().getImage();
       	  		  	tmpImg= tmpImg.getScaledInstance(-1, 140, Image.SCALE_SMOOTH);
       	  		  	spRoom.setIcon(new ImageIcon(tmpImg));
                		
            	}
            	else{	
            		spRoom.setIcon(droppedRoom.getScaledImage(140));
            	}
            }
        	
        	if(droppedRoom!=null)
        		spRoom.setToolTipText(droppedRoom.getName());
        }
       
        spaceRoom.setPreferredSize(new Dimension((int)(spWidth+spWidth*0.2),(int)(spHeight+spHeight*0.1)));
		spaceRoom.setBorder(loweredbevel);
		spaceRoom.add(spRoom);

		
        spaceCharacter =new JPanel();
        spaceCharacter.setBackground(Color.DARK_GRAY);
        JLabel spCharacter = new JLabel("Personaggio");
        spCharacter.setFont(new Font("SensSerif", Font.BOLD, 12));
        spCharacter.setForeground(Color.LIGHT_GRAY);
        new MyDropTargetListener(spaceCharacter,spCharacter,1);
        spaceCharacter.setPreferredSize(new Dimension((int)(spWidth+spWidth*0.2),(int)(spHeight+spHeight*0.1)));
        spaceCharacter.setBorder(loweredbevel);
		spaceCharacter.add(spCharacter);

        
        spaceWeapon =new JPanel();
        spaceWeapon.setBackground(Color.DARK_GRAY);
        JLabel spWeapon = new JLabel("Arma");
        spWeapon.setFont(new Font("SensSerif", Font.BOLD, 12));
        spWeapon.setForeground(Color.LIGHT_GRAY);
        new MyDropTargetListener(spaceWeapon,spWeapon,2);
        spaceWeapon.setPreferredSize(new Dimension((int)(spWidth+spWidth*0.2),(int)(spHeight+spHeight*0.1)));
        spaceWeapon.setBorder(loweredbevel);
        spaceWeapon.add(spWeapon);

        
		cardsPanel.add(Box.createRigidArea(new Dimension(SPACEBETWCARDS,0)));
        cardsPanel.add(spaceCharacter);
		cardsPanel.add(Box.createRigidArea(new Dimension(SPACEBETWCARDS,0)));
        cardsPanel.add(spaceWeapon);
        cardsPanel.add(Box.createRigidArea(new Dimension(SPACEBETWCARDS,0)));
        cardsPanel.add(spaceRoom);
		cardsPanel.add(Box.createRigidArea(new Dimension(SPACEBETWCARDS,0)));

		
		warningMessage=new JTextPane();
		warningMessage.setEditable(false);
		warningMessage.setBackground(formulateWind.getBackground());
		warningMessage.setForeground(Color.RED);
		
		
		evaluateDroppedCards(type.equals("solution"));
		
		JPanel btn= new JPanel();
        btn.setBackground(formulateWind.getBackground());
		btn.setLayout(new BoxLayout(btn, BoxLayout.X_AXIS));
		
		
		JButton cancelBtn= new JButton("Annulla");
		cancelBtn.addActionListener(this);
		cancelBtn.setActionCommand("Annulla");
		btn.add(cancelBtn);
		btn.add(Box.createRigidArea(new Dimension(10,0)));
					
		sendBtn= new JButton("Invia");
		sendBtn.setEnabled(false);
		sendBtn.addActionListener(this);
		sendBtn.setActionCommand("Invia");
		sendBtn.setAlignmentX(Component.CENTER_ALIGNMENT);
		
		
        btn.add(sendBtn);
        
        
        JPanel wrapCards= new JPanel();
		
        wrapCards.add(cardsPanel);
        wrapCards.setBackground(formulateWind.getBackground());
        
        formulateWindContent.add(solAssumpText);
        formulateWindContent.add(wrapCards);
        formulateWindContent.add(Box.createRigidArea(new Dimension(0,10)));
        formulateWindContent.add(warningMessage);
        formulateWindContent.add(Box.createRigidArea(new Dimension(0,10)));
        formulateWindContent.add(btn); 
        formulateWindContent.add(Box.createRigidArea(new Dimension(0,10)));
        
 		formulateWind.add(formulateWindContent);
		formulateWind.pack();
		formulateWind.setLocationRelativeTo(centerPanel);
		formulateWind.setVisible(true);
		
		log.printLog("MainWindow: la finestra di formulazione ipotesi/soluzione (formulateWind) e' stata creata");
		
	}
	
	public void closeRefuteWindow() {
		if (refuteWind!=null) {
			refuteWind.dispose();
			refuteWind=null;
		}
		
	}
	
	/**
	 * Aggiunge testo all'area delle informazioni
	 * @param player il giocatore che ha inviato l'informazione 
	 * 		oppure il player che ha confutato la mia ipotesi se il parametro type e' "Refuted" 
	 * 		oppure il nuovo proprietario del gruppo se il parametro type e' "ChangeOwner"
	 * 		oppure il player a cui ho confutato l'ipotesi se il parametro type e' "RefuteSent"
	 * @param info informazione supplementare che ha un certo significato in base al parametro type
	 * @param type tipo di informazione (usato per creare le informazioni)
	 */
	public void writeInfo(Zombie player,String info,String type){
		
		
		if(!myPlayer.getState().isGroupMember()) return; // se sono nello stato ALONE non comunico alcuna info
		
		log.printLog("MainWindow: sto per scrivere un'informazione nell'area delle info; i parametri passati " +
				"al metodo writeInfo() sono: player --> "+player.getNickname()+", info --> "+info+", type --> "+type);
		
		boolean typeOK=false;
		
		String playerName= player.getNickname();

		Color playerColor = myPlayer.getPlayerColor(playerName);
		
		StyledDocument doc = westPanel.getInfoArea().getStyledDocument();
		SimpleAttributeSet textStyle = new SimpleAttributeSet();
        StyleConstants.setFontFamily(textStyle,"Plain");
        StyleConstants.setFontSize(textStyle, 14);
        
        StyleConstants.setForeground(textStyle,Color.BLACK);

        SimpleAttributeSet nameStyle = new SimpleAttributeSet();
        StyleConstants.setBold(nameStyle,true);
        StyleConstants.setFontSize(nameStyle, 16);
 
        StyleConstants.setForeground(nameStyle,playerColor);
        
        boolean areYou=false;
        
        if(playerName.equals(myPlayer.getNickname()))
        	areYou=true;
		
		
		if(type.equals("Refuted")){ //un player ha confutato la mia ipotesi
				typeOK=true;
				
				try{
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "ha confutato la tua ipotesi con la carta ["+info+"]\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			
			
		}
		
		else if(type.equals("RefuteSent")){ // l'ipotesi di un player e' stata confutata
			typeOK=true;
			
			try{
				
				doc.insertString(doc.getLength(), "Hai confutato l'ipotesi di ",nameStyle);
			    doc.insertString(doc.getLength(),playerName+" ",textStyle);
			    doc.insertString(doc.getLength(),"con la carta ["+info+"]\n",nameStyle);
			   
			} catch(BadLocationException exc) {
				exc.printStackTrace();
			}
		
		
		}
		
		
		else if(type.equals("WrongAssumption")){ //l'ipotesi del player e' stata confutata
			typeOK=true;
			
			if(areYou){
				try{
					
					doc.insertString(doc.getLength(), "Hai effettuato un'ipotesi errata\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					/* non scrivo chi mi ha confutato l'ipotesi
			    	perche' potrei avere barato e quindi mi sono confutato l'ipotesi da solo*/
					doc.insertString(doc.getLength(), "l'ipotesi di ",textStyle);
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "e' risultata sbagliata\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
		}
			
		else if(type.equals("Assumption")){ //il player ha fatto un'ipotesi
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Hai effettuato l'ipotesi ["+info+"]\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "ha effettuato l'ipotesi ["+info+"]\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
		}
		
		
		else if(type.equals("Solution")){ //il player ha dato la soluzione
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Hai formulato la soluzione ["+info+"]\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "ha formulato la soluzione ["+info+"]\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			
		}
		
		
		else if(type.equals("OutGrp")){ //il player a fine partita ha scelto di uscire dal gruppo
			typeOK=true;
			
			if(areYou){
				//questo caso non si puo' presentare perche' il player che ha premuto "esci dal gruppo" ha gia' effettuato
				// il dispose della MainWindow
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "ha abbandonato il gruppo\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			
		}
		
		else if(type.equals("PlayAgain")){ //il player e' uscito per ricominciare la partita rimanendo nel gruppo
			typeOK=true;
			
			if(areYou){
				//questo caso non si puo' presentare perche' il player che ha premuto ricomincia ha gia' effettuato
				// il dispose della MainWindow
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "vuole ricominciare la partita\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			
		}
		
		else if(type.equals("EndTurn")){ //il player ha terminato il suo turno
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Hai terminato il tuo turno\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "ha terminato il suo turno\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
		}
			
		
		else if(type.equals("MyFirstTurn")){ //il player ha il primo turno
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Sei il primo a giocare\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(), "Il primo turno e' di ",textStyle);
					doc.insertString(doc.getLength(),playerName+"\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
		}
		
		else if(type.equals("MyTurn")){ //il player ha il turno
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "E' il tuo turno\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(), "E' il turno di ",textStyle);
					doc.insertString(doc.getLength(),playerName+"\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
		}
		
		else if(type.equals("ChangeOwner")){ //c'e' un nuovo proprietario
			typeOK=true;
			
			SimpleAttributeSet oldOwnerStyle = new SimpleAttributeSet();
	        StyleConstants.setBold(oldOwnerStyle,true);
	        StyleConstants.setFontSize(oldOwnerStyle, 16);
	 
	        StyleConstants.setStrikeThrough(oldOwnerStyle, true);
			
			if(areYou){ //sono io il nuovo proprietario
				
				try {
					doc.insertString(doc.getLength()," "+info+" ",oldOwnerStyle);
					doc.insertString(doc.getLength(), " non e' piu' il proprietario del gruppo\n",textStyle);
					doc.insertString(doc.getLength(),"Il nuovo proprietario sei tu\n",nameStyle);
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
				
			}
			
			else{
				try{
					doc.insertString(doc.getLength()," "+info+" ",oldOwnerStyle);
					doc.insertString(doc.getLength(), " non e' piu' il proprietario del gruppo\nIl nuovo proprietario e' ",textStyle);
					doc.insertString(doc.getLength(),playerName+"\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			
		}
			
		else if(type.equals("ThrowDice")){ //il player ha tirato il dado
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Hai tirato il dado\nHai ottenuto un "+info+"\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName,nameStyle);
					doc.insertString(doc.getLength(), " ha tirato il dado.\nHa ottenuto un " +info+"\n",textStyle);
					
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			
			
		}
		else if(type.equals("Winner")){ //il player ha vinto
			typeOK=true;

			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Complimenti.Hai vinto\nLa partita e' terminata\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName,nameStyle);
					doc.insertString(doc.getLength(), " ha vinto. Di conseguenza tu...\nLa partita e' terminata\n",textStyle);
					
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
		}
		
		else if(type.equals("Loser")){ //il player ha perso, ha dato una soluzione sbagliata, e' stato eliminato
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "La soluzione che hai dato e' errata\nSei stato eliminato\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(), "La soluzione data da ",textStyle);
					doc.insertString(doc.getLength(),playerName,nameStyle);
					doc.insertString(doc.getLength(), " e' errata\nE' stato eliminato\n",textStyle);
					
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
		}
		
		else if(type.equals("LoserPlayAgain")){ //il player ha perso, ha dato una soluzione sbagliata, e' ancora nel gruppo (erano rimasti a giocare in 2)
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "La soluzione che hai dato e' errata\nLa partita e' terminata\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(), "La soluzione data da ",textStyle);
					doc.insertString(doc.getLength(),playerName,nameStyle);
					doc.insertString(doc.getLength(), " e' errata\nHai vinto.\nLa partita e' terminata\n",textStyle);
					
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
		}
		
		else if(type.equals("Exit")){ //il player e' uscito
			typeOK=true;
			
			if(areYou){
				//questo caso non si puo' presentare perche' il player che ha premuto esci ha gia' effettuato
				// il dispose della MainWindow
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "e' uscito dalla partita\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
		}
		
		else if(type.equals("Room")){ //il player si e' spostato nella stanza
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Sei entrato nella stanza "+info+"\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), " e' entrato nella stanza "+info+"\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			
		}
		
		else if(type.equals("MovePawn")){ //il player ha spostato la sua pedina
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Hai spostato la pedina"+"\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			else{
				
				try{
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "ha spostato la pedina"+"\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
				
			}
			
		}
		
		else if(type.equals("Cheat")){ //ho barato e nessuno ha confutato la mia ipotesi
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Nessuno ha confutato la tua\nipotesi ma almeno una delle carte\nfaceva parte delle tue.\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			else{
				
				try{
					doc.insertString(doc.getLength(), "L'ipotesi di ",textStyle);
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "non e' stata confutata"+"\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
				
			}
			
		}
		else if(type.equals("NotCheat")){ //non ho barato nessuno ha confutato la mia ipotesi
			typeOK=true;
			
			if(areYou){
				try{
					doc.insertString(doc.getLength(), "Nessuno ha confutato la tua\nipotesi.\nHai la soluzione.\n",nameStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
			}
			else{
				
				try{
					doc.insertString(doc.getLength(), "L'ipotesi di ",textStyle);
					doc.insertString(doc.getLength(),playerName+" ",nameStyle);
					doc.insertString(doc.getLength(), "non e' stata confutata"+"\n",textStyle);
				} catch(BadLocationException exc) {
					exc.printStackTrace();
				}
				
			}
			
		}
		else{
			
			typeOK=false;
			log.printErr("MainWindow: tipo di informazione "+ type +" non riconosciuto");
			return;
		}
		
		if(typeOK){
			try {
				doc.insertString(doc.getLength(),"\n\n",nameStyle);
				SimpleAttributeSet center = new SimpleAttributeSet();
				StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
				doc.setParagraphAttributes(0, doc.getLength(), center, false);
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
			
			log.printLog("Ho scritto l'informazione nell'area delle info");
		}
		
		
	}
	
	
	/**
	 * Crea la finestra di confutazione ipotesi
	 * @param player il giocatore che ha fatto l'ipotesi
	 * @param character la carta personaggio ipotizzata
	 * @param weapon la carta arma ipotizzata
	 * @param room la carta della stanza ipotizzata 
	 */
	public void createRefuteWind(Zombie player, Character character,Weapon weapon, Room room){
		
		log.printLog("MainWindow: creo la finestra di confutazione ipotesi (refuteWind) con i parametri: " +
				"player --> "+player.getNickname()+", character ---> "+character+", weapon --> "+weapon+", room --> "+room);
		
		if(resAssumptionWind!=null){
			resAssumptionWind.dispose();
			resAssumptionWind=null;
		}
		
		refutePlayer = player;
		refuteWind= new JDialog(frame);
		
		String playerName = player.getNickname();
		
		refuteWind.setTitle("Confutare l'ipotesi di "+playerName);
		refuteWind.setModal(false); //voglio interagire con la chat
		
		refuteWind.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		
		refuteWind.setBackground(Color.DARK_GRAY);
		
		JPanel refuteOuterPane = new JPanel();
		
		refuteOuterPane.setBackground(refuteWind.getBackground());
		
		refuteOuterPane.setLayout(new BoxLayout(refuteOuterPane, BoxLayout.Y_AXIS));
		
		JTextPane refuteText= new JTextPane();
				
		StyledDocument doc = refuteText.getStyledDocument();
		
		refuteText.setBackground(refuteWind.getBackground());
		refuteText.setEditable(false);
		
        SimpleAttributeSet textStyle = new SimpleAttributeSet();
        SimpleAttributeSet nameStyle = new SimpleAttributeSet();
               
		 StyleConstants.setForeground(textStyle ,Color.WHITE);
	     StyleConstants.setFontFamily(textStyle ,"Helvetica");
	     StyleConstants.setFontSize(textStyle , 18);
	     
	     
	     StyleConstants.setForeground(nameStyle,myPlayer.getPlayerColor(playerName));
	     StyleConstants.setFontFamily(nameStyle ,"Helvetica");
	     StyleConstants.setFontSize(nameStyle , 20);
	     
	     try {
	    	doc.insertString(doc.getLength(),"Seleziona UNA carta per confutare l'ipotesi di ",textStyle);
			doc.insertString(doc.getLength(),playerName,nameStyle);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	     
	     SimpleAttributeSet center = new SimpleAttributeSet();
	     StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
	     
	     doc.setParagraphAttributes(0, doc.getLength(), center, false);
	     
		refuteText.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));		
		
		
		refuteOuterPane.add(refuteText);
		refuteOuterPane.add(Box.createRigidArea(new Dimension(20,0)));
		
		JPanel refuteCardsPane = new JPanel();	
		refuteCardsPane.setLayout(new BoxLayout(refuteCardsPane, BoxLayout.X_AXIS));
		
		refuteCardsPane.setBackground(refuteWind.getBackground());
		
		JPanel refuteCardPane;
		
		JLabel refuteLab;
	
		
		LinkedList<Card> cards = myPlayer.getMyCards();
		
		int i=1;
		for(Card c : cards){
				
				refuteCardPane = new JPanel();
				refuteCardPane.setBackground(refuteWind.getBackground());
				refuteCardPane.setLayout(new BoxLayout(refuteCardPane, BoxLayout.Y_AXIS));
				refuteLab = new JLabel();
				refuteLab.setIcon (c.getScaledImage(SCALECARD));
				refuteLab.setToolTipText(c.getName());
				refuteLab.setAlignmentX(JButton.CENTER_ALIGNMENT);
				refuteLab.setEnabled(false);
				refuteLab.setBackground(refuteWind.getBackground());
		
				if ((character.equals(c) || room.equals(c) || weapon.equals(c))){ 
					refuteLab.addMouseListener(new RefuteHandler(c));
					refuteLab.setBorder(BorderFactory.createLineBorder(Color.RED,5));
				} else{
					// se la mia carta e' diversa da quelle dell'ipotesi allora non puo' confutarla
					refuteLab.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
					
				}
				
				
				refuteCardPane.add(refuteLab);
				refuteCardsPane.add(refuteCardPane);
					
				if(i%3==0 || i==cards.size()){
					refuteOuterPane.add(refuteCardsPane);
					refuteOuterPane.add(Box.createRigidArea(new Dimension(20,0)));
					refuteCardsPane = new JPanel();
					refuteCardsPane.setBackground(refuteWind.getBackground());
					refuteCardsPane.setLayout(new BoxLayout(refuteCardsPane, BoxLayout.X_AXIS));
				}
				i++;
				
		}
						
		
		JButton refuteOk =new JButton("Confuta");
		refuteOk.setAlignmentX(JButton.CENTER_ALIGNMENT);
		refuteOk.addActionListener(this);
		refuteOk.setActionCommand("RefuteSend");
		refuteOuterPane.add(Box.createRigidArea(new Dimension(0,5)));
		refuteOuterPane.add(refuteOk);
		refuteOuterPane.add(Box.createRigidArea(new Dimension(0,10)));
				
		refuteWind.add(refuteOuterPane);
		
		refuteWind.pack();
		refuteWind.setLocationRelativeTo(centerPanel);
		refuteWind.setVisible(true);
		
		log.printLog("MainWindow: la finestra di confutazione ipotesi (refuteWind) e' stata creata");
		
	}
	
	
	/**
	 * Restituisce il pannello centrale della MainWindow
	 * @return vedi descrizione
	 */
	public CenterPanel getCenterPanel(){
		
		return centerPanel;
		
	}
	
	/**
	 * Restituisce il pannello East della MainWindow
	 * @return vedi descrizione
	 */
	public EastPanel getEastPanel(){
		
		return eastPanel;
		
	}
	
	/**
	 * Crea la finestra che restituisce il risultato ottenuto dalla 
	 * formulazione di un'ipotesi nel caso questa non fosse corretta
	 * @param refuted true se la mia ipotesi e' stata confutata, false se non e' stata confutata
	 * ma ho sbagliato ugualmente l'ipotesi perche' ho usato carte che ho in mano.
	 * Se refuted e' false gli altri 2 parametri non vengono utilizzati
	 * @param player il giocatore che ha confutato l'ipotesi
	 * @param card la carta con la quale ha confutato l'ipotesi
	 * @param cheat se ho formulato un'ipotesi utilizzando carte in mio possesso (ho barato)
	 */
	public void createResWind(boolean refuted,Zombie player, Card c, boolean cheat){
		
		log.print("MainWindow: creo la finestra \"Risultato Ipotesi\" (resAssumptionWind) con i seguenti parametri: " +
				"refuted --> "+ refuted);
		if(player==null) log.printLog(", player --> null, c --> "+c);
		else log.printLog(", player --> "+player.getNickname()+", c --> "+c);
		
		resAssumptionWind= new JDialog(frame);
		resAssumptionWind.setModal(false); //voglio interagire con la chat
		resAssumptionWind.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		resAssumptionWind.addWindowListener(this);
		resAssumptionWind.setBackground(Color.DARK_GRAY);
		resAssumptionWind.setResizable(false);
		
		
		JPanel resOuterPane = new JPanel();
		
		resOuterPane.setBackground(resAssumptionWind.getBackground());
		
		resOuterPane.setLayout(new BoxLayout(resOuterPane, BoxLayout.Y_AXIS));
		
		JTextPane resText= new JTextPane();
		
		StyledDocument doc = resText.getStyledDocument();
		
		resText.setBackground(resAssumptionWind.getBackground());
		resText.setEditable(false);
		
		SimpleAttributeSet textStyle = new SimpleAttributeSet();
		StyleConstants.setForeground(textStyle ,Color.WHITE);
	    StyleConstants.setFontFamily(textStyle ,"Helvetica");
	    StyleConstants.setFontSize(textStyle , 14);
	    StyleConstants.setBold(textStyle, true);
		
		if(refuted){ //qualcuno ha confutato la mia ipotesi
			String playerName = player.getNickname();
			resAssumptionWind.setTitle("Confutata");
			
			
			 SimpleAttributeSet nameStyle = new SimpleAttributeSet();
			 StyleConstants.setForeground(nameStyle,myPlayer.getPlayerColor(playerName));
		     StyleConstants.setFontFamily(nameStyle ,"Helvetica");
		     StyleConstants.setBold(nameStyle, true);
		     StyleConstants.setFontSize(nameStyle , 16);
		     
		     try {
		    	 	doc.insertString(doc.getLength(),playerName+" ",nameStyle);
			    	doc.insertString(doc.getLength(),"ha confutato la tua ipotesi\n" +
			    			"con la carta \""+ c.getName()+"\"",textStyle);	
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
		     
		     resText.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
		}
		
		else{ //nessuno ha confutato la mia ipotesi
			resAssumptionWind.setTitle("Ipotesi non confutata");
			
			if(cheat){ //avevo barato nel formulare l'ipotesi
			
				try {
			    	doc.insertString(doc.getLength(),"La tua ipotesi non e' stata confutata\n" +
			    			"ma non era corretta in quanto\n" +
			    			"hai usato delle carte in tuo possesso\n\n" +
			    			"Stai forse cercando di depistare le indagini?",textStyle);
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			
			}
			
			else{ //non aveve barato nel formulare l'ipotesi
				
				 SimpleAttributeSet winStyle = new SimpleAttributeSet();
				 StyleConstants.setForeground(winStyle,Color.GREEN);
			     StyleConstants.setFontFamily(winStyle ,"Helvetica");
			     StyleConstants.setBold(winStyle, true);
			     StyleConstants.setFontSize(winStyle , 16);
				
				try {
			    	doc.insertString(doc.getLength(),"La tua ipotesi non e' stata confutata\n\n",textStyle);
			    	doc.insertString(doc.getLength(),"Hai la soluzione\n\n",winStyle);
			    	doc.insertString(doc.getLength(),"Formula adesso la soluzone\n\n",textStyle);
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
				
			}
			
			resText.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
		}
				
		
		 SimpleAttributeSet center = new SimpleAttributeSet();
	     StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
	     doc.setParagraphAttributes(0, doc.getLength(), center, false);
				
	    		
	     
	    resOuterPane.add(resText);
		resOuterPane.add(Box.createRigidArea(new Dimension(0,10)));		
		
		
		if(refuted){
			JLabel resLab=new JLabel();
			resLab.setIcon (c.getScaledImage(SCALECARD));
			resLab.setToolTipText(c.getName());
			resLab.setAlignmentX(JButton.CENTER_ALIGNMENT);
			resLab.setBackground(resAssumptionWind.getBackground());
			resOuterPane.add(resLab);
			resOuterPane.add(Box.createRigidArea(new Dimension(0,10)));
		}
		
		
		
		JButton resSol =new JButton("Soluzione");
		resSol.setAlignmentX(JButton.CENTER_ALIGNMENT);
		resSol.addActionListener(this);
		resSol.setActionCommand("ResSol");
		
		JButton resEndTurn =new JButton("Fine Turno");
		resEndTurn.setAlignmentX(JButton.CENTER_ALIGNMENT);
		resEndTurn.addActionListener(this);
		resEndTurn.setActionCommand("ResEndTurn");
		
		resOuterPane.add(resSol);
		resOuterPane.add(Box.createRigidArea(new Dimension(0,10)));
		resOuterPane.add(resEndTurn);
		resOuterPane.add(Box.createRigidArea(new Dimension(0,10)));
				
		resAssumptionWind.add(resOuterPane);
		
		resAssumptionWind.pack();
		resAssumptionWind.setLocationRelativeTo(centerPanel);
		resAssumptionWind.setVisible(true);
		
		log.printLog("MainWindow: la finestra \"Risultato Ipotesi\" (resAssumptionWind) e' stata creata");
		
	}
	
	/**
	 * Imposta una carta come non valida ai fini della soluzione
	 * @param c la carta da scartare dalla soluzione
	 */
	public void discardCard(Card c){
		
		westPanel.discardCard(c);
	}
	
	/**
	 * restituisce il tabellone
	 * @return vedi descrizione
	 */
	public BoardPanel getBoard(){
		
	return this.centerPanel.getBoard();
		
	}
	

	@Override
	public void actionPerformed(ActionEvent e) {
		
		String action = e.getActionCommand();
		
		if(action.equals("endExit")){ // finestra endWind
			
			log.printLog("MainWindow: ho premuto il tasto per uscire da Cluedo nella endWind");
			
			//esco da Cluedo
			System.out.println("MainWindow: esco da Cluedo");
			endWind.dispose();
			endWind=null;
			frame.dispose();
			myPlayer.exit();
		}
		
		else if(action.equals("endGrp")){ // finestra endWind
						
			log.printLog("MainWindow: ho premuto il tasto per tornare alla selezione gruppi nella endWind, invio il multicastSendInfo per comunicare " +
					"che esco dal gruppo");

			//ritorno alla sezione gruppi, sono fuori da qualsiasi gruppo
			System.out.println("MainWindow: torno alla selezione gruppi");
			if(myPlayer.getState().isGroupMember()) 
				myPlayer.multicastSendInfo(myPlayer.getNickname(),"","OutGrp");
			
			// se ho perso, sono gia' fuori dal gruppo, ho premuto il tasto per cambiare gruppo non invio l'info
			endWind.dispose();
			endWind=null;
			frame.dispose();
			myPlayer.returnGroupWind();
		}
		
		else if(action.equals("endAgain")){ // finestra endWind 
			
			log.printLog("MainWindow: ho premuto il tasto per ricominciare la partita nella endWind, invio il multicastSendInfo per " +
					"comunicare la mia intenzione a voler ricominciare la partita");
			
			//ritorno alla sezione gruppi, sono ancora dentro al gruppo
			if(myPlayer.getState().isGroupMember()) 
				myPlayer.multicastSendInfo(myPlayer.getNickname(),"","PlayAgain");
			//se ho perso, sono gia' fuori dal gruppo, ho premuto il tasto per uscire da Cluedo non invio l'info
			endWind.dispose();
			endWind=null;
			frame.dispose();
			myPlayer.returnAgain();
			
		}
		
		else if(action.equals("RefuteSend")){
			
			if(refuteCard==null) return; //la carta non e' stata selezionata non fare niente
			
			refuteWind.dispose();
			refuteWind=null;
			
			log.printLog("MainWindow: Ho selezionato la carta "+refuteCard+" che puo' confutare l'ipotesi di "+ refutePlayer.getNickname() +" e ho premuto il tasto confuta nella finestra refuteWind. " +
					"Adesso faccio il multicastRefuteAssumption per comunicarlo");
			
			myPlayer.multicastRefuteAssumption(myPlayer.getNickname(),refuteCard);

			System.out.println("MainWindow: ho confutato l'ipotesi di "+ refutePlayer.getNickname() +" con la carta "+refuteCard);
			
			refutePlayer = null;
			refuteCard=null;
			refuteLab=null;

			
		}
		
		else if(action.equals("Dado")){ //lancio il dado
						
			this.diceNum=eastPanel.rollDice();
			
			this.isDiceThrow=true;
			
			log.printLog("MainWindow: ho lanciato il dado (ho ottenuto "+diceNum+"), ora invio il multicastSendInfo per comunicare il " +
					"numero ottenuto agli altri (prima pero' chiamo i metodi dell'EastPanel stopTimer() e disableAllGameBtn())");
			
			eastPanel.stopTimer();
			
			eastPanel.disableAllGameBtn();
			
			myPlayer.multicastSendInfo(myPlayer.getNickname(),""+diceNum,"ThrowDice");

			//controlla in quali caselle ci possiamo muovere con il numero ottenuto
			centerPanel.getBoard().findMoveCells(diceNum);

			//adesso il player puo' muovere la sua pedina nel tabellone	
						
		}
		
		else if (action.equals("FineTurno")){
			
			if(roomWind!=null){
				roomWind.dispose();
				roomWind=null;
			}
			
			setIsAssumptionChecked(false);
			
			centerPanel.getBoard().hideSecretPassage();
			
			eastPanel.stopTimer();
			myPlayer.multicastSendInfo(myPlayer.getNickname(),"","EndTurn");
			myPlayer.multicastEndTurn(myPlayer.getNickname(), false);
			
		}
		
		else if(action.equals("Ipotesi/Soluzione")){
			
			centerPanel.getBoard().hideSecretPassage();

			enterInRoom(-1,-1);
			
		}
		
		else if(action.equals("Soluzione") || action.equals("Ipotesi")){
			
			
			if(roomWind!=null){
				roomWind.dispose();
				roomWind=null;
			}
			
			if(action.equals("Soluzione")){
				solutionTime=true;
				centerPanel.getBoard().hideSecretPassage();
				log.printLog("MainWindow: ho premuto il tasto soluzione nella roomWind, adesso visualizzero' la finestra formulateWind per la soluzione " +
						"(prima pero' eseguiti i metodi dell'EastPanel stopTimer() e disableAllGameBtn())");
			}
			else{
				
				solutionTime=false;
				log.printLog("MainWindow: ho premuto il tasto ipotesi nella roomWind, adesso visualizzero' la finestra formulateWind per l'ipotesi " +
						"(prima pero' vengono eseguiti i metodi dell'EastPanel stopTimer() e disableAllGameBtn())");
			}
			
			//centerPanel.getBoard().hideSecretPassage();
			
			//se ero nel tab stanza e sto facendo un'ipotesi ritorno al tab personaggio in quanto non posso fare il drag&drop delle stanze
			JTabbedPane tabPane=westPanel.getTabbedPane();
			if(tabPane.getSelectedIndex()>1 && solutionTime==false)
			 tabPane.setSelectedIndex(0);
			
			eastPanel.stopTimer();
			eastPanel.disableAllGameBtn();
			
			
			if(solutionTime){
				
				showformulateWindow("solution");
			
			}
		
			else{
			
				showformulateWindow("assumption");
			
			}
			
		}
		
		else if(action.equals("Annulla")){ //ritorno alla schermata di gioco
			log.printLog("MainWindow: ho premuto il tasto annulla nella finestra formulateWind");
			droppedCh=null;
			droppedWeap=null;
			droppedRoom=null;
			formulateWind.dispose();
			formulateWind=null;
			eastPanel.enableGameBtn(isDiceThrow,isAssumptionChecked);
		}
		
		else if(action.equals("Invia")){ //invia soluzione/ipotesi
			//questo tasto e' abilitato automaticamente quando le carte sono presenti nel pannello 
			
			formulateWind.dispose();
			formulateWind=null;
			
			String myName=myPlayer.getNickname();
						
			if(character==null || weapon==null || room==null){
				System.err.println("MainWindow: errore nel rilevamento della soluzione");
				return;
			}
			
			
			boolean rightFormulation=false;
			
			//ho formulato una soluzione o un'ipotesi, verifico localmente se e' esatta
			if (droppedCh.equals(character) && droppedWeap.equals(weapon) && droppedRoom.equals(room))
				rightFormulation=true;
			
			if(solutionTime){
				
				setIsAssumptionChecked(false);
				
				log.printLog("MainWindow: ho premuto invia con la soluzione ["+droppedCh+", "+droppedWeap+", "+droppedRoom+"], adesso " +
						"invio il multicastSendInfo per comunicarlo agli altri");
				myPlayer.multicastSendInfo(myName,""+droppedCh+", "+droppedWeap+", "+droppedRoom+"","Solution");
				System.out.println("MainWindow: ho dato la soluzione ["+droppedCh+", "+droppedWeap+", "+droppedRoom+"]");

				
			}else{
				
				if(!rightFormulation){
					
					log.printLog("MainWindow: ho premuto invia con l'ipotesi errata ["+droppedCh+", "+droppedWeap+", "+droppedRoom+"], adesso " +
							"invio il multicastSendInfo per comunicarlo agli altri");
					myPlayer.multicastSendInfo(myName,""+droppedCh+", "+droppedWeap+", "+droppedRoom+"","Assumption");
					
				}
				else{
					
					log.printLog("MainWindow: ho premuto invia con l'ipotesi corretta ["+droppedCh+", "+droppedWeap+", "+droppedRoom+"], adesso " +
							"invio il multicastSendInfo per comunicarlo agli altri");
					 //la mia ipotesi e' corretta
					myPlayer.multicastSendInfo(myName,""+droppedCh+", "+droppedWeap+", "+droppedRoom+"","Assumption");
					
				}
				
				System.out.println("MainWindow: ho formulato l'ipotesi ["+droppedCh+", "+droppedWeap+", "+droppedRoom+"]");

			}
			
			if(solutionTime){
			
				if (rightFormulation){
					// se la soluzione e' corretta ho vinto e lo comunico a tutti (la partita e' finita)
					
					log.printLog("MainWindow: Ho verificato localmente la mia soluzione ed e' risultata esatta. " +
							"Invio un multicastSendInfo per aggiornare l'area delle info con la mia vittoria e poi un multicastWinPlayer" +
							"per comunicare agli altri che la partita e' terminata perche' ho vinto\n");
					myPlayer.multicastSendInfo(myName,"","Winner");
					
					System.out.println("MainWindow: Ho vinto la partita");
					
					myPlayer.multicastWinPlayer(myName); /* questo permette di creare la finestra vincitore/perdente
													  di ogni player */
					
					//e' inutile passare il turno (la partita e' finita)
					
					return;
				}
				else{ //ho formulato una soluzione ed ho perso
					log.printLog("MainWindow: La soluzione che ho dato e' errata, ho perso.");
					myPlayer.wrongSolution();
					}
			}
			else{ // ho fatto un'ipotesi e deve essere verificata
				centerPanel.waitRefute();			
				myPlayer.sendAssumption(droppedCh,droppedWeap,droppedRoom);
			}
			
			droppedCh=null;
			droppedWeap=null;
			droppedRoom=null;
			
		}
		else if(action.equals("Help")){
			
			if(helpWind==null){
				log.printLog("MainWindow: Apro la finestra d'aiuto");
				helpWind=new Help(this.frame,this);
			}
			
		}
		else if(action.equals("Close")){
			log.printLog("MainWindow: Chiudo la finestra d'aiuto");
			helpWind.dispose();
			helpWind=null;
			
		}
		
		else if(action.equals("GrpExit")){ //torna alla finestra di selezione gruppi
			
			exitWind.dispose();
			exitWind=null;
			
			frame.dispose();
			
			log.printLog("MainWindow: ho premuto il tasto per tornare alla finestra di selezione gruppi nell'exitWind. Invio il multicastSendInfo" +
					"per comunicarlo agli altri");
			
			myPlayer.multicastSendInfo(myPlayer.getNickname(),"","OutGrp");
						
			//thread separato per liberare l'interfaccia grafica
			/*myPlayer.addOrderedThread(new Runnable(){
				
				public void run(){*/
					myPlayer.returnGroupWind();
				/*}
				 * 		
			});*/
			
			
			
		}
		
		else if(action.equals("Exit")){ //esci da cluedo
			
			exitWind.dispose();
			exitWind=null;
			
			frame.dispose();
			
			log.printLog("MainWindow: ho premuto il tasto per uscire da Cluedo nell'exitWind. Invio il multicastSendInfo" +
					"per comunicarlo agli altri");
			
			myPlayer.multicastSendInfo(myPlayer.getNickname(),"","Exit");
		
			
			//thread separato per liberare interfaccia grafica
			/*myPlayer.addOrderedThread(new Runnable(){
				
				public void run(){*/
					myPlayer.exit();
			/*	}
								
			});*/
			
			
		}
		else if(action.equals("CancelExit")){ //annulla uscita
			
			exitWind.dispose();
			exitWind=null;
			
			log.printLog("MainWindow: ho premuto il tasto annulla nell'exitWind.");

		}
		
		else if(action.equals("ResEndTurn")){ //cliccato termina il turno sulla finestra che mostra il risultato della confutazione di un'ipotesi
						
			resAssumptionWind.dispose();
			resAssumptionWind=null;
			
			setIsAssumptionChecked(false);
			
			log.printLog("MainWindow: ho premuto il tasto OK sulla finestra resAssumptionWind.");

			myPlayer.multicastSendInfo(myPlayer.getNickname(),"","EndTurn");
			myPlayer.multicastEndTurn(myPlayer.getNickname(),false);
			
		}
		
		else if(action.equals("ResSol")){ // premuto sul tasto soluzione della finestra resAssumptionWind
			
			resAssumptionWind.dispose();
			resAssumptionWind=null;
			
			ActionEvent event= new ActionEvent(this,1,"Soluzione");
						
			actionPerformed(event);
			
			log.printLog("MainWindow: ho premuto il tasto Soluzione sulla finestra resAssumptionWind.");

			
		}

	}
	
	/**
	 * Segna se il dado e' gia' stato tirato oppure no
	 * @param b true se il dado e' gia' stato tirato, false altrimenti
	 */
	public void setIsDiceThrow(boolean b){
		
		log.printLog("MainWindow: imposto la variabile isDiceThrow (che segnala se il dado e' gia' stato tirato) ="+b);
		
		isDiceThrow=b;
	}

	@Override
	public void windowOpened(WindowEvent e) {
		
	}

	/**
	 * Gestisce la richiesta di chiusura della MainWindow.
	 * Viene chiesto all'utente se tornare alla finestra iniziale di registrazione
	 * dei gruppi oppure uscire completamente dal gioco
	 */
	public void mainWindowClosing() {

		
		if(exitWind!=null) // evita che siano aperte piu' exitWind contemporaneamente
			return;
		
		if(endWind!=null) // se e' gia' presente la finestra di fine gioco e' inutile visualizzare anche quella di uscita
			return;
		
		log.printLog("MainWindow: creo la finestra di uscita (exitWind)");
		
		exitWind = new JDialog(frame);
		
		exitWind.setTitle("Vuoi uscire?");
		exitWind.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		exitWind.setBackground(Color.DARK_GRAY);
		exitWind.setResizable(false);
		
		
		JPanel exitPanel= new JPanel();
		
		exitPanel.setBackground(exitWind.getBackground());
		
		exitPanel.setLayout(new BoxLayout(exitPanel,BoxLayout.Y_AXIS));

		JTextPane exitText= new JTextPane();
		
		StyledDocument doc = exitText.getStyledDocument();
		
		exitText.setBackground(exitWind.getBackground());
		exitText.setEditable(false);
		
        SimpleAttributeSet textStyle = new SimpleAttributeSet();
               
		 StyleConstants.setForeground(textStyle ,Color.WHITE);
	     StyleConstants.setFontFamily(textStyle ,"Helvetica");
	     StyleConstants.setFontSize(textStyle , 15);
	     StyleConstants.setBold(textStyle,true);
	     
		// chiedo se vuole uscire completamente o tornare alla finestra di selezione gruppi
	     
	     try {
	    	doc.insertString(doc.getLength(),"\nVuoi tornare alla finestra iniziale\n\n" +
						"di selezione dei gruppi\n\noppure " +
						"vuoi uscire\n\ncompletamente dal gioco?\n",textStyle);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	     
	     SimpleAttributeSet center = new SimpleAttributeSet();
	     StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
	     
	     doc.setParagraphAttributes(0, doc.getLength(), center, false);
	     
	     
	    JPanel exitBtnPane= new JPanel();
	    
	    exitBtnPane.setBackground(exitWind.getBackground());
	     
	    JButton exitGrp = new JButton ("Inizio");
	    exitGrp.addActionListener(this);
	    exitGrp.setActionCommand("GrpExit");
		exitBtnPane.add(Box.createRigidArea(new Dimension(10,0)));
		exitBtnPane.add(exitGrp);
		exitBtnPane.add(Box.createRigidArea(new Dimension(10,0)));
		
		
		JButton exit = new JButton ("Esci");
		exit.addActionListener(this);
		exit.setActionCommand("Exit");
	
		exitBtnPane.add(exit);
		exitBtnPane.add(Box.createRigidArea(new Dimension(10,0)));
		
		
		
		JButton cancelExit = new JButton ("Annulla");
		cancelExit.addActionListener(this);
		cancelExit.setActionCommand("CancelExit");
		
		exitBtnPane.add(cancelExit);
		exitBtnPane.add(Box.createRigidArea(new Dimension(10,0)));
	     
		
	    exitPanel.add(exitText);
	    exitPanel.add(exitBtnPane);
	    exitPanel.add(Box.createRigidArea(new Dimension(0,10)));
		
	    exitWind.setContentPane(exitPanel);
		
		exitWind.setModal(false); //voglio interagire con la chat
		
		exitWind.pack();
		
		exitWind.setLocationRelativeTo(centerPanel);
		
		exitWind.setVisible(true);
		
		log.printLog("MainWindow: la finestra di uscita (exitWind) e' stata creata");
		
	}
	
	@Override
	public void windowClosing(WindowEvent e) {
		if(e.getSource()==frame){ // finestra frame
			// chiusura MainWindow
			log.printLog("MainWindow: Chiusura finestra MainWindow (frame di MainWindow). Verra' creata finestra exitWind");
			mainWindowClosing();
			
		}
		else if(e.getSource()==endWind){ // finestra endWind 
			//chiusura finestra vincitore/perdente
			
			log.printLog("MainWindow: Chiusura finestra endWind. Invio un multicastSendInfo agli altri player per " +
					"comunicar loro la mia intenzione di rigiocare");
			
			//equivale ad aver premuto il tasto ricomincia
			//ritorno alla sezione gruppi, sono ancora dentro al gruppo
			myPlayer.multicastSendInfo(myPlayer.getNickname(),"","PlayAgain");
			endWind.dispose();
			endWind=null;
			frame.dispose();
			myPlayer.returnAgain();
		}
		else if(e.getSource()==formulateWind){ // finestra formulateWind
			log.printLog("MainWindow: Chiusura finestra formulateWind");
			droppedCh=null;
			droppedWeap=null;
			droppedRoom=null;
			formulateWind.dispose();
			formulateWind=null;
			eastPanel.enableGameBtn(isDiceThrow,isAssumptionChecked);

		}
		else if(e.getSource()==roomWind){ // finestra roomWind
			log.printLog("MainWindow: Chiusura finestra roomWind");
			roomWind.dispose();
			roomWind=null;
			eastPanel.enableGameBtn(isDiceThrow,isAssumptionChecked);
		}
		else if(e.getSource()==resAssumptionWind){ // finestra resAssumptionWind
			log.printLog("MainWindow: Chiusura finestra resAssumptionWind");
			resAssumptionWind.dispose();
			resAssumptionWind=null;
			eastPanel.enableGameBtn(true,isAssumptionChecked);
		}
		else if(e.getSource()==helpWind){ // finestra helpWind
			log.printLog("MainWindow: Chiusura finestra helpWind");
			helpWind.dispose();
			helpWind=null;
		}
	}

	@Override
	public void windowClosed(WindowEvent e) {
		
	}

	@Override
	public void windowIconified(WindowEvent e) {
		
	}

	@Override
	public void windowDeiconified(WindowEvent e) {
		
	}

	@Override
	public void windowActivated(WindowEvent e) {
		
	}

	@Override
	public void windowDeactivated(WindowEvent e) {
		
	}
	 
	/** Classe che controlla il drop delle carte sulla finestra di formulazione ipotesi/soluzione */
	private class MyDropTargetListener extends DropTargetAdapter {
	    private DropTarget dropTarget;
	    private JLabel spaceLbl;
	    private JPanel parentPane;
	    private int num=0; //num==1 e' il pannello personaggio, num==2 e' il pannello arma

	    public MyDropTargetListener(JPanel parentPane, JLabel spaceLbl,int num) {
	      this.spaceLbl = spaceLbl;
	      this.parentPane=parentPane;
	      this.num=num;
	      dropTarget = new DropTarget(parentPane, DnDConstants.ACTION_COPY, this, true, null);
	    }

	    public void drop(DropTargetDropEvent event) {
	      try {
	        Transferable tr = event.getTransferable();
	        ImageIcon imagIcon = (ImageIcon) tr.getTransferData(TransferableCard.imageFlavor);
	        if (event.isDataFlavorSupported(TransferableCard.imageFlavor)) {
	          if(isWeapDragged && (num==1 || num==3)){ //la carta che voglio droppare e' un'arma ma la sto droppando nel pannello personaggio o stanza
	        	     event.rejectDrop();
	        	     return;
	          }
		      else if((isChDragged) && (num==2 || num==3)){ //la carta che voglio droppare e' un personaggio ma la sto droppando nel pannello arma o stanza
		        	 event.rejectDrop();
		        	 return;
		      }
		      else if(((!isChDragged) && (!isWeapDragged) && (num==1 || num==2)) || (num==3 && solutionTime==false)){ 
		    	  //la carta che voglio droppare e' una stanza ma la sto droppando nel pannello arma o personaggio oppure non sto formulando una soluzione
		        	 event.rejectDrop();
		        	 return;
		      }
	          
	          
	          event.acceptDrop(DnDConstants.ACTION_COPY);
	          spaceLbl.setText("");
	          Image tmpImg= imagIcon.getImage();
	  		  tmpImg= tmpImg.getScaledInstance(-1, 140, Image.SCALE_SMOOTH);
	  		  if(spaceLbl.getIcon()==null) numDroppedCard++;
	          spaceLbl.setIcon(new ImageIcon(tmpImg));
	          event.dropComplete(true);
	          if((numDroppedCard==2 && !solutionTime) || (numDroppedCard==3 && solutionTime))
	        	  sendBtn.setEnabled(true);
	          if(isChDragged){
	        	  droppedCh = draggedCh;
	        	  spaceLbl.setToolTipText(droppedCh.getName());
	        	  /* ho appena importato una carta personaggio quindi visualizzo il tab arma */
	        	  westPanel.getTabbedPane().setSelectedIndex(1); 
	          }
	          else if(isWeapDragged){
	        	  droppedWeap = draggedWeap;
	        	  spaceLbl.setToolTipText(droppedWeap.getName());
	        	  if(solutionTime)
	        	  /* ho appena importato una carta arma quindi visualizzo il tab stanza */
	        		  westPanel.getTabbedPane().setSelectedIndex(2);
	        	  else
	        		  /* ho appena importato una carta arma quindi visualizzo il tab personaggio */
	        		  westPanel.getTabbedPane().setSelectedIndex(0);
	        		  
	          }
	          else{     	  
	        	  droppedRoom=draggedRoom;
	        	  spaceLbl.setToolTipText(droppedRoom.getName());
	        	  /* ho appena importato una carta stanza quindi visualizzo il tab personaggio */
	        	  westPanel.getTabbedPane().setSelectedIndex(0);
	          }
	          
	          evaluateDroppedCards(solutionTime);
	          draggedWeap = null;
	          draggedCh=null;
	          draggedRoom=null;
	          isWeapDragged=false;
	          isChDragged=false;
	          return;
	        }
	        event.rejectDrop();
	      } catch (Exception e) {
	        e.printStackTrace();
	        event.rejectDrop();
	      }
	    }
	  }
	
	
	/**
	 * Controlla se il player ha droppato nella formulateWind anche carte che erano gia' state scartate ai fini della soluzione
	 * per dargli un opportuno messaggio informativo
	 * @param solution sto formulando una soluzione
	 */
	public void evaluateDroppedCards(boolean solution){
		
		log.printLog("MainWindow: Controllo se l'ipotesi o soluzione che sto formulando usa carte gia' scartate");
		
		String roomName=null;
		
		LinkedList<Card> myCards=myPlayer.getMyCards();
		
		boolean wrongRoom=false;
		
		if(!solution){ //sto facendo un'ipotesi, la carta stanza e' quella in cui mi trovo
			
			roomName=myPlayer.getPawn().getRoomName();
		}
		
		else{ // sto formulando una soluzione
			
			if(droppedRoom!=null)
				roomName=droppedRoom.getName();
			
		
		}
		
		
		if(roomName!=null){
		
			for(Card c: myCards){
				
				if(c.getName().equals(roomName)){ // sto formulando un'ipotesi/soluzione su una stanza che so non essere quella del delitto
					wrongRoom=true;
					break;
				}
				
			}
			
			if(westPanel.isDiscardedCard(new Room(roomName)))
				wrongRoom=true;
		}
		
		
        warningMessage.setText("");
		
		
		if((droppedCh!=null && droppedCh.isDeleted()) || (droppedWeap!=null && droppedWeap.isDeleted()) || wrongRoom){ //una delle carte e' sicuramente sbagliata
		
			StyledDocument document = warningMessage.getStyledDocument();

	        Style warningStyle = warningMessage.addStyle("Warning", null);
	        StyleConstants.setBackground(warningStyle, formulateWind.getBackground());
	        StyleConstants.setForeground(warningStyle, Color.RED);
	        StyleConstants.setFontFamily(warningStyle ,"Helvetica");
		    StyleConstants.setFontSize(warningStyle , 14);
		    StyleConstants.setBold(warningStyle,true);
			
			if(solutionTime){
				try {
					document.insertString(document.getLength()," ATTENZIONE: la soluzione che stai formulando \n ti portera' sicuramente alla sconfitta: \n" +
							" usi una o piu' carte gia' scartate.",warningStyle);
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			}else{ //ipotesi
				try {
					document.insertString(document.getLength()," ATTENZIONE: la tua ipotesi e' sicuramente sbagliata: \n" +
							" usi una o piu' carte gia' scartate. \n" +
							" Se il tuo obiettivo e' confondere gli altri fai pure. ",warningStyle);
				} catch (BadLocationException e) {
					e.printStackTrace();
				}
			}
			
			SimpleAttributeSet center = new SimpleAttributeSet();
			StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
			document.setParagraphAttributes(0, document.getLength(), center, false);
			
			warningMessage.setVisible(true);
			formulateWind.pack();
			log.printLog("MainWindow: L'ipotesi o soluzione che sto formulando usa carte gia' scartate");

		}
		
		else{
			warningMessage.setVisible(false);
			formulateWind.pack();
			log.printLog("MainWindow: L'ipotesi o soluzione che sto formulando NON usa carte gia' scartate");

		}
		
	}
	
	
	
	/** classe usata per gestire la selezione della carta che confuta l'ipotesi*/
	private class RefuteHandler implements MouseListener{

		Card card; // la carta che confuta l'ipotesi 
		
		public RefuteHandler(Card c){
			card=c;
		}
		
		@Override
		public void mouseClicked(MouseEvent e) {
			
			JLabel refLab=(JLabel) e.getSource();
			
			refuteCard=card;
			if(refuteLab!=null){
				refuteLab.setBorder(BorderFactory.createLineBorder(Color.RED,5));
				refuteLab.setEnabled(false);
			} 
			refuteLab=refLab;
			refLab.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
			refLab.setEnabled(true);
			
		}

		@Override
		public void mousePressed(MouseEvent e) {
			
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			
		}

		@Override
		public void mouseExited(MouseEvent e) {
			
		}
		
		
	}

}
